/**
Nectarine Utility Project is a software interface for the web system 'demovibes'
Copyright (C) 2010  Alexandre LAURENT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

website: http://code.google.com/p/nectarine-utility-project/
e-mail: lw.demoscene@gmail.com
**/

#include "onelinerwidget.h"

#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QListWidget>
#include <QLabel>
#include <QWebView>
#include <QWebFrame>
#include <QLineEdit>
#include <QList>
#include <QRegExp>

#include <QDir>
#include <QFile>

#include <QMenu>

#include <QUrl>
#include <QDesktopServices>

#include <QAction>

#include <QShowEvent>
#include <QSignalMapper>

#include <QDebug>

#include "onelinerviewer.h"
#include "onelinertoolbox.h"

#include "utils.h"
#include "../globals.h"

OnelinerWidget :: OnelinerWidget(QWidget* parent)
    :QWidget(parent),isConnected(false)
{
    // Layout construction
    pMainHGrid = new QHBoxLayout(this);
    pUsersGrid = new QGridLayout();
    pOnelinerGrid = new QVBoxLayout();

    // User online part
    pUsersOnlineLabel = new QLabel(tr("Users online:"),this);
    pUsersOnlineLabel->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
    pUserListWidget = new QListWidget(this);

    // Defining some size property ( this list of user should rake just a small place )
    pUserListWidget->setMinimumWidth(100);
    pUserListWidget->setMaximumWidth(100);
    pUserListWidget->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Minimum);

    // Set the menu for the user
    pUserNameSignalMapper = new QSignalMapper(this);
    pRequesUserPageSignalMapper = new QSignalMapper(this);
    pUserPMSignalMapper = new QSignalMapper(this);
    pUserProfileSignalMapper = new QSignalMapper(this);
    pUserMenu = new QMenu(this);
    pUserNameAction = Utils::addActionInMenu(this,pUserMenu,QIcon(),tr("Send Oneliner message"),"","",pUserNameSignalMapper,SLOT(map()),false);
    pRequestUserPageAction = Utils::addActionInMenu(this,pUserMenu,QIcon(),tr("See user page"),"","",pRequesUserPageSignalMapper,SLOT(map()));
    pUserPMAction = Utils::addActionInMenu(this,pUserMenu,QIcon(),tr("Send PM (Open Internet Browser)"),"","",pUserPMSignalMapper,SLOT(map()));
    pUserProfileAction = Utils::addActionInMenu(this,pUserMenu,QIcon(),tr("Open User Profile (Open Internet Browser)"),"","",pUserProfileSignalMapper,SLOT(map()));

    // The chat viewer
    pOnelinerViewer = new OnelinerViewer(this);
    pOnelinerViewer->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); // Set that we will manage ourselves the links
    pOnelinerViewer->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);

    // The tool box ( all is done in the child class )
    pOnelinerToolBox = new OnelinerToolBox(this);
    pOnelinerToolBox->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);

    // The place to enter messages
    pInput = new QLineEdit(this);

    // Putting objects in the interface
    pMainHGrid->addLayout(pUsersGrid);
        pUsersGrid->addWidget(pUsersOnlineLabel,0,0,Qt::AlignHCenter);
        pUsersGrid->addWidget(pUserListWidget,1,0);
    pMainHGrid->addLayout(pOnelinerGrid);
        pOnelinerGrid->addWidget(pOnelinerViewer/*,0,0*/);
        pOnelinerGrid->addWidget(pOnelinerToolBox/*,1,0*/);
        pOnelinerGrid->addWidget(pInput/*,2,0*/);

    // Connections
    connect(pInput, SIGNAL(returnPressed()), this, SLOT(validateMessage()));

    connect(pUserListWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(openUserMenu(QListWidgetItem*)));
    connect(pUserNameSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(addNameInMessage(const QString&)));
    connect(pRequesUserPageSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(goToUserPageViewer(const QString&)));
    connect(pUserPMSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(openPMPage(const QString&)));
    connect(pUserProfileSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(openProfilePage(const QString&)));

    connect(pOnelinerViewer, SIGNAL(linkClicked(QUrl)), this, SLOT(needOpenLink(QUrl)));

    // For the tool box
    connect(pOnelinerToolBox->getBoldAction(), SIGNAL(triggered()), this, SLOT(addBold()));
    connect(pOnelinerToolBox->getItalicAction(), SIGNAL(triggered()), this, SLOT(addItalic()));
    connect(pOnelinerToolBox->getUnderlineAction(), SIGNAL(triggered()), this, SLOT(addUnderlined()));
    connect(pOnelinerToolBox->getStrikeAction(), SIGNAL(triggered()), this, SLOT(addStriked()));

        // Colours
    connect(pOnelinerToolBox->getSignalMapper(), SIGNAL(mapped(const QString&)), this, SLOT(addTag(const QString&)));
    connect(pOnelinerToolBox, SIGNAL(needUserColour(QColor)), this, SLOT(addUserColour(QColor)));

    connect(pOnelinerToolBox, SIGNAL(needSong(uint)), this, SLOT(addSong(uint)));
    connect(pOnelinerToolBox, SIGNAL(needArtist(uint)), this, SLOT(addArtist(uint)));
    connect(pOnelinerToolBox, SIGNAL(needUser(QString)), this, SLOT(addUser(QString)));
    connect(pOnelinerToolBox, SIGNAL(needGroup(uint)), this, SLOT(addGroup(uint)));
    connect(pOnelinerToolBox, SIGNAL(needCompilation(uint)), this, SLOT(addCompilation(uint)));
    connect(pOnelinerToolBox, SIGNAL(needForum(uint)), this, SLOT(addForum(uint)));
    connect(pOnelinerToolBox, SIGNAL(needThread(uint)), this, SLOT(addThread(uint)));
    connect(pOnelinerToolBox, SIGNAL(needFlag(QString)), this, SLOT(addFlag(QString)));

    initParser();
    nbNewMessages = 0;

    // Remove / set focus on the correct object
    pUserListWidget->setFocusPolicy(Qt::NoFocus);
    pOnelinerViewer->setFocusPolicy(Qt::NoFocus);
    pInput->setFocus(Qt::OtherFocusReason);

    qDebug() << "OnelinerWidget created";
}

OnelinerWidget :: ~OnelinerWidget(void)
{
    delete pUsersGrid;
    delete pOnelinerGrid;

    qDebug() << "OnelinerWidget deleted";
}

void OnelinerWidget :: initParser(void)
{
    qDebug() << "OnelinerWidget :: initParser";

    // Build the list of keywords for the smiley
    smileyKeywords.insert(QString(":necta:"), QString(SMILEYS_DIR) + QString("support-our-fruits.gif"));
    smileyKeywords.insert(QString(":nectawall:"), QString(SMILEYS_DIR) + QString("nectawall.gif"));
    smileyKeywords.insert(QString("^^"), QString(SMILEYS_DIR) + QString("^^.jpg"));
    smileyKeywords.insert(QString(":)"), QString(SMILEYS_DIR) + QString("ab.gif"));
    smileyKeywords.insert(QString(":-)"), QString(SMILEYS_DIR) + QString("ab.gif"));
    smileyKeywords.insert(QString(":("), QString(SMILEYS_DIR) + QString("ac.gif"));
    smileyKeywords.insert(QString(":-("), QString(SMILEYS_DIR) + QString("ac.gif"));
    smileyKeywords.insert(QString(";)"), QString(SMILEYS_DIR) + QString("ad.gif"));
    smileyKeywords.insert(QString(";-)"), QString(SMILEYS_DIR) + QString("ad.gif"));
    smileyKeywords.insert(QString(":p"), QString(SMILEYS_DIR) + QString("ae.gif"));
    smileyKeywords.insert(QString(":P"), QString(SMILEYS_DIR) + QString("ae.gif"));
    smileyKeywords.insert(QString(":-p"), QString(SMILEYS_DIR) + QString("ae.gif"));
    smileyKeywords.insert(QString(":-P"), QString(SMILEYS_DIR) + QString("ae.gif"));
    smileyKeywords.insert(QString(":D"), QString(SMILEYS_DIR) + QString("ag.gif"));
    smileyKeywords.insert(QString(":-D"), QString(SMILEYS_DIR) + QString("ag.gif"));
    smileyKeywords.insert(QString("8)"), QString(SMILEYS_DIR) + QString("af.gif"));
    smileyKeywords.insert(QString("8-)"), QString(SMILEYS_DIR) + QString("af.gif"));
    smileyKeywords.insert(QString(":up:"), QString(SMILEYS_DIR) + QString("ah.gif"));
    smileyKeywords.insert(QString(":O"), QString(SMILEYS_DIR) + QString("ai.gif"));
    smileyKeywords.insert(QString(":-O"), QString(SMILEYS_DIR) + QString("ai.gif"));
    smileyKeywords.insert(QString("O_o"), QString(SMILEYS_DIR) + QString("ai.gif"));
    smileyKeywords.insert(QString(":*"), QString(SMILEYS_DIR) + QString("aj.gif"));
    smileyKeywords.insert(QString(":X"), QString(SMILEYS_DIR) + QString("al.gif"));
    smileyKeywords.insert(QString(":-X"), QString(SMILEYS_DIR) + QString("al.gif"));
    smileyKeywords.insert(QString(":angry:"), QString(SMILEYS_DIR) + QString("angry.png"));
    smileyKeywords.insert(QString(":ass:"), QString(SMILEYS_DIR) + QString("ass.gif"));
    smileyKeywords.insert(QString(":stop:"), QString(SMILEYS_DIR) + QString("av.gif"));
    smileyKeywords.insert(QString(":up:"), QString(SMILEYS_DIR) + QString("ay.gif"));
    smileyKeywords.insert(QString(":rotfl:"), QString(SMILEYS_DIR) + QString("bj.gif"));
    smileyKeywords.insert(QString(":cake:"), QString(SMILEYS_DIR) + QString("cake.png"));
    smileyKeywords.insert(QString(":clap:"), QString(SMILEYS_DIR) + QString("clap.gif"));
    smileyKeywords.insert(QString("coffee"), QString(SMILEYS_DIR) + QString("coffee.png"));
    smileyKeywords.insert(QString(":|"), QString(SMILEYS_DIR) + QString("confused.png"));
    smileyKeywords.insert(QString(";("), QString(SMILEYS_DIR) + QString("crying.png"));
    smileyKeywords.insert(QString(":gothpony:"), QString(SMILEYS_DIR) + QString("goth_pony.png"));
    smileyKeywords.insert(QString(":love:"), QString(SMILEYS_DIR) + QString("heart.png"));
    smileyKeywords.insert(QString(":heart:"), QString(SMILEYS_DIR) + QString("heart.png"));
    smileyKeywords.insert(QString(":he-man:"), QString(SMILEYS_DIR) + QString("he-man.gif"));
    smileyKeywords.insert(QString(":lol:"), QString(SMILEYS_DIR) + QString("lol.gif"));
    smileyKeywords.insert(QString(":mypony:"), QString(SMILEYS_DIR) + QString("pony.gif"));
    smileyKeywords.insert(QString(":mypinkpony:"), QString(SMILEYS_DIR) + QString("pony2.gif"));
    smileyKeywords.insert(QString("puke"), QString(SMILEYS_DIR) + QString("puke.gif"));
    smileyKeywords.insert(QString(":silly:"), QString(SMILEYS_DIR) + QString("silly.png"));
    smileyKeywords.insert(QString(":slap:"), QString(SMILEYS_DIR) + QString("slap.gif"));
    smileyKeywords.insert(QString(":sleepy:"), QString(SMILEYS_DIR) + QString("sleepy.png"));
    smileyKeywords.insert(QString(":starving:"), QString(SMILEYS_DIR) + QString("starving.png"));
    smileyKeywords.insert(QString(":strongman:"), QString(SMILEYS_DIR) + QString("strongman.gif"));
    smileyKeywords.insert(QString(":twisted:"), QString(SMILEYS_DIR) + QString("twisted.gif"));
    smileyKeywords.insert(QString(":victory:"), QString(SMILEYS_DIR) + QString("victory.png"));

    //Fill the colours list
    colourTags.push_back("red");
    colourTags.push_back("blue");
    colourTags.push_back("green");
    colourTags.push_back("brown");
    colourTags.push_back("cyan");
    colourTags.push_back("darkblue");
    colourTags.push_back("gold");
    colourTags.push_back("grey");
    colourTags.push_back("magenta");
    colourTags.push_back("orange");
    colourTags.push_back("pink");
    colourTags.push_back("purple");
    colourTags.push_back("white");
    colourTags.push_back("yellow");
    colourTags.push_back("black");

    // Last checking
    // Check if all the files inserted for the keywords are correct
    QList<QString> listValues(smileyKeywords.values());
    for ( QList<QString>::const_iterator it_filename = listValues.begin() ; it_filename != listValues.end() ; ++it_filename )
        if ( !QFile::exists(*it_filename) )
            qDebug() << "This smiley does not exist: " << *it_filename;
}

void OnelinerWidget :: parseOnelinerMessages(void)
{
    qDebug() << "OnelinerWidget :: parseOnelinerMessages";

    for ( int i = nbNewMessages-1 ; i >= 0 ; i-- ) // Invert order to not break the order of the messages
    {
        QString parsedMessage = onelinerData[i].message;

        this->parseBBCode(parsedMessage);
        this->parseSmileys(parsedMessage);

        // Construction of the final HTML tags with the message / author / flags
        parsedOnelinerData.prepend
        (
            QString("<p>") +
            QString("<span><img src='") + Utils::getFlagPathFromName(onelinerData[i].flag) + QString("' class='countryflag' alt='flag' title='") + onelinerData[i].flag + QString("' />") +
            QString("<a href=\"") + DEFAULT_SERVER + QString("/demovibes/user/") + onelinerData[i].author + QString("/\" title=\"User\" >") + onelinerData[i].author + QString("</a>") +
            QString("</span>") +
            QString("<span style=\"color: #777; float: right; margin: auto; text-align: right;\">(") + onelinerData[i].time.toString("HH:mm:ss") + QString(")</span>") +
            QString("<br />") +
            QString("<span>") + parsedMessage + QString("</span>") +
            QString("</p>")
        );
    }
}

void OnelinerWidget :: parseBBCode(QString& message)const
{
    qDebug() << "OnelinerWidget :: parseBBCode";

    // Italic parsing
    message.replace(QRegExp("\\[i\\](.*)\\[/i\\]"), "<i>\\1</i>");

    // Bold parsing
    message.replace(QRegExp("\\[b\\](.*)\\[/b\\]"), "<b>\\1</b>");

    // Underlined parsing
    message.replace(QRegExp("\\[u\\](.*)\\[/u\\]"), "<u>\\1</u>");

    // Strikethrough parsing
    message.replace(QRegExp("\\[s\\](.*)\\[/s\\]"), "<s>\\1</s>");

    // Colour parsing
    for ( QList<QString>::const_iterator it_colours = colourTags.begin() ; it_colours != colourTags.end() ; ++it_colours )
            message.replace(QRegExp(QString("\\[") + QString(*it_colours) + QString("\\](.*)\\[/") + QString(*it_colours) + QString("\\]")), QString("<span style=\"color: ") + QString(*it_colours) + QString("\">\\1</span>"));

    //Colour second parsing (user colours)
    // ToDO check the code generated by the oneliner on the website
    message.replace(QRegExp("\\[color=(#.{6})\\](.*)\\[/color\\]"), "<span style=\"color:\\1\">\\2</span>");

    // Url parsing
    // ToDo check if it is correct
    message.replace(QRegExp("((https?://)|(www.))(\\S*)"), QString("<a href=\"http://\\4\">http://\\4</a> "));

    // User parsing
    message.replace(QRegExp("\\[user\\](.*)\\[/user\\]"), QString("<a href='") + DEFAULT_SERVER + QString(USER_PATH) + QString("\\1\\'>\\1</a>"));

    // Artist parsing
    message.replace(QRegExp("\\[artist\\](.*)\\[/artist\\]"), QString("<a href='") + DEFAULT_SERVER + QString(ARTIST_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("user_green.png'/>\\1</a>"));

    // Group parsing
    message.replace(QRegExp("\\[group\\](.*)\\[/group\\]"), QString("<a href='") + DEFAULT_SERVER + QString(GROUP_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("group.png'/>\\1</a>"));

    // Thread parsing
    message.replace(QRegExp("\\[thread\\](\\d*)\\[/thread\\]"), QString("<a href='") + DEFAULT_SERVER + QString(THREAD_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("newspaper.png'/>\\1</a>"));

    // Forum parsing
    message.replace(QRegExp("\\[forum\\](.*)\\[/forum\\]"), QString("<a href='") + DEFAULT_SERVER + QString(FORUM_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("newspaper.png'/>\\1</a>"));

    // Song parsing
    message.replace(QRegExp("\\[song\\](.*)\\[/song\\]"), QString("<a href='") + DEFAULT_SERVER + QString(SONG_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("music.png'/>\\1</a>"));

    // Label parsing
    message.replace(QRegExp("\\[label\\](.*)\\[/label\\]"), QString("<img src='") + QString(ICONSDIR) + QString("label.png'/>\\1</a>"));

    // compilation parsing
    message.replace(QRegExp("\\[compilation](.*)\\[/compilation\\]"), QString("<a href='") + DEFAULT_SERVER + QString(COMPILATION_PATH) + QString("\\1'><img src='") + QString(ICONSDIR) + QString("compilation.png'/>\\1</a>"));


    // Flag parsing
    QRegExp flagRE("\\[flag\\](.*)\\[/flag\\]");
    flagRE.exactMatch(message);
    if ( flagRE.matchedLength() > 13 )
    {
        message.replace(flagRE,QString("<img src='") + Utils::getFlagPathFromName(flagRE.cap(1).toLower()) + QString("'/>"));
    }
}

void OnelinerWidget :: parseSmileys(QString& message)const
{
    QList<QString> listKeywords(smileyKeywords.keys());

    qDebug() << "OnelinerWidget :: parseSmileys";

    for ( QList<QString>::const_iterator it_keywords = listKeywords.begin() ; it_keywords != listKeywords.end() ; ++it_keywords )
        if ( message.contains((*it_keywords),Qt::CaseSensitive) )
        {
            message.replace(QString((*it_keywords)), QString("<img src='")+ QString(smileyKeywords.value(*it_keywords)) + QString("' title=\"" + *it_keywords + "\" />"));
        }
}

void OnelinerWidget :: updateWebView(void)
{
    QString htmlData = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";

    qDebug() << "OnelinerWidget :: updateWebView";

    for ( QList<QString>::const_iterator it_message = parsedOnelinerData.begin() ; it_message != parsedOnelinerData.end() ; it_message++ )
    {
        htmlData.append(*it_message);
    }

    qDebug() << "OnelinerWidget :: viewer set to: " << QDir::currentPath() + QString("/");
    pOnelinerViewer->setHtml(htmlData,QDir::currentPath() + QString("/"));
}

void OnelinerWidget :: addTag(const QString& tag)
{
    QString inputText = pInput->text();
    int cursorPos = pInput->cursorPosition();

    qDebug() << "OnelinerWidget :: addTag" << tag;

    if ( pInput->hasSelectedText() )
    {
        QString selectedText = pInput->selectedText();

        qDebug() << "OnelinerWidget :: addTag -> text: " << inputText << " Cursor pos: " << cursorPos  << " selected: " << selectedText << " size: " << selectedText.size() << " Result of the test: " << inputText.indexOf(selectedText,cursorPos);

        // The cursor pos can be at the end of the selected text, or at the beginning.
        // To check this, we are checking if the selected text is foundable just after the cursor index
        if ( inputText.indexOf(selectedText,cursorPos) == cursorPos)
        {
            qDebug() << " Selected text found (cursor before the text)";
            // We are putting the closing tag at the end because the other one change the size and the index of the cursor
            inputText.insert(cursorPos + selectedText.size(), QString("[/") + tag + QString("]"));
            inputText.insert(cursorPos, QString("[") + tag + QString("]"));
        }
        else
        {
            qDebug() << " Selected text found (cursor after the selection)";

            // We have to move the cursor with the size of the selected text
            // We are putting the closing tag at the end because the other one change the size and the index of the cursor
            inputText.insert(cursorPos , QString("[/") + tag + QString("]"));
            inputText.insert(cursorPos - selectedText.size(), QString("[") + tag + QString("]"));
        }
    }
    else
    {
        inputText.insert(cursorPos, QString("[") + tag + QString("]") + QString("[/") + tag + QString("]"));
    }

    pInput->setText(inputText);
}

void OnelinerWidget :: addUserColourTag(const QColor& c)
{
    QString inputText = pInput->text();
    int cursorPos = pInput->cursorPosition();
    char colour[7] = "000000";  // Default is black

    sprintf(colour, "%02X%02X%02X",c.red(),c.green(),c.blue());

    qDebug() << "OnelinerWidget :: addUserColourTag -> " << c << " Colour String: " << colour;

    if ( pInput->hasSelectedText() )
    {
        QString selectedText = pInput->selectedText();

        qDebug() << "OnelinerWidget :: addTag -> text: " << inputText << " Cursor pos: " << cursorPos  << " selected: " << selectedText << " size: " << selectedText.size() << " Result of the test: " << inputText.indexOf(selectedText,cursorPos);

        // The cursor pos can be at the end of the selected text, or at the beginning.
        // To check this, we are checking if the selected text is foundable just after the cursor index
        if ( inputText.indexOf(selectedText,cursorPos) == cursorPos)
        {
            qDebug() << " Selected text found (cursor before the text)";
            // We are putting the closing tag at the end because the other one change the size and the index of the cursor
            inputText.insert(cursorPos + selectedText.size(), QString("[/color]"));
            inputText.insert(cursorPos, QString("[color=#") + QString(colour) + QString("]"));
        }
        else
        {
            qDebug() << " Selected text found (cursor after the selection)";

            // We have to move the cursor with the size of the selected text
            // We are putting the closing tag at the end because the other one change the size and the index of the cursor
            inputText.insert(cursorPos, QString("[/color]"));
            inputText.insert(cursorPos - selectedText.size(), QString("[color=#") + QString(colour) + QString("]"));
        }
    }
    else
    {
        inputText.insert(cursorPos, QString("[color=#") + QString(colour) + QString("]") + QString("[/color]"));
    }

    pInput->setText(inputText);
}

void OnelinerWidget :: setUserList(const QList<User>& userOnline)
{
    qDebug() << "OnelinerWidget :: setUserList";

    pUserListWidget->clear();
    for ( QList<User>::const_iterator itUsers = userOnline.begin() ; itUsers != userOnline.end() ; itUsers++ )
    {
        QListWidgetItem* pItem = new QListWidgetItem(itUsers->name,pUserListWidget);
        pItem->setData(Qt::DecorationRole, QIcon(Utils::getFlagPathFromName(itUsers->flag)));
        pItem->setToolTip(usToString(itUsers->status));
    }
}

void OnelinerWidget :: setMessagesData(const QList<OMessage>& messages)
{
    qDebug() << "OnelinerWidget :: setMessagesData";

    // Count the number of new messages
    if ( onelinerData.count() != 0 ) // We have already load once the oneliner so we have to compare with the last message
    {
        nbNewMessages = 0;
        for (QList<OMessage>::const_iterator it_message = messages.begin() ; it_message != messages.end() && onelinerData[0] != *it_message ; it_message++ )
        {
            nbNewMessages++;
        }
    }
    else
    {
        nbNewMessages = messages.count();
    }

    this->onelinerData = messages;

    this->parseOnelinerMessages();

    this->updateWebView();
}

void OnelinerWidget :: validateMessage()
{
    qDebug() << "OnelinerWidget :: validateMessage " << pInput->text();

    emit needSendMessage(pInput->text());
    pInput->clear();
    //pOnelinerViewer->
}

void OnelinerWidget :: needOpenLink(const QUrl& url)
{
    qDebug() << "OnelinerViewer :: needOpenLink " << url;

    QDesktopServices::openUrl(url);
}

void OnelinerWidget :: addBold(void)
{
    qDebug() << "OnelinerWidget :: addBold";

    this->addTag("b");
}

void OnelinerWidget :: addItalic(void)
{
    qDebug() << "OnelinerWidget :: addItalic";

    this->addTag("i");
}

void OnelinerWidget :: addUnderlined(void)
{
    qDebug() << "OnelinerWidget :: addUnderlined";

    this->addTag("u");
}

void OnelinerWidget :: addStriked(void)
{
    qDebug() << "OnelinerWidget :: addStriked";

    this->addTag("s");
}

void OnelinerWidget :: addUserColour(QColor colour)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    this->addUserColourTag(colour);
}

void OnelinerWidget :: addSong(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addSong" << id;

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[song]%1[/song]").arg(id)));
}

void OnelinerWidget :: addArtist(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addArtist" << id;

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[artist]%1[/artist]").arg(id)));
}

void OnelinerWidget :: addUser(QString name)
{
    qDebug() << "OnelinerWidget :: addUser" << name;

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[user]") + name + QString("[/user]")));
}

void OnelinerWidget :: addGroup(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[group]%1[/group]").arg(id)));
}

void OnelinerWidget :: addCompilation(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[compilation]%1[/compilation]").arg(id)));
}

void OnelinerWidget :: addForum(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[forum]%1[/forum]").arg(id)));
}

void OnelinerWidget :: addThread(unsigned int id)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[thread]%1[/thread]").arg(id)));
}

void OnelinerWidget :: addFlag(QString flag)
{
    qDebug() << "OnelinerWidget :: addUserColour";

    pInput->setText(pInput->text().insert(pInput->cursorPosition(),QString("[flag]") + flag + QString("[/flag]")));
}

QString OnelinerWidget :: getOnelinerData(void)
{
    qDebug() << "OnelinerWidget :: getOnelinerData";

    return pOnelinerViewer->page()->currentFrame()->toHtml();
}

void OnelinerWidget :: showEvent(QShowEvent* pSE)
{
    qDebug() << "OnelinerWidget :: showEvent";

    pInput->setFocus();
    pSE->accept();
}

void OnelinerWidget :: setConnection(const bool enabled)
{
    qDebug() << "OnelinerWidget :: setConnection " << enabled;

    isConnected = enabled;

    pInput->setVisible(enabled);
    pOnelinerToolBox->setVisible(enabled);
    pUserNameAction->setEnabled(true);
}

void OnelinerWidget :: openUserMenu(QListWidgetItem* pLWI)
{
    qDebug() << "OnelinerWidget :: openUserMenu " << pLWI->text();

    // Disabling old messages
    pUserNameSignalMapper->removeMappings(pUserNameAction);
    pRequesUserPageSignalMapper->removeMappings(pRequestUserPageAction);
    pUserPMSignalMapper->removeMappings(pUserPMAction);
    pUserProfileSignalMapper->removeMappings(pUserProfileAction);

    // Set the link between the username and the slots
    pUserNameSignalMapper->setMapping(pUserNameAction,pLWI->text());
    pRequesUserPageSignalMapper->setMapping(pRequestUserPageAction,pLWI->text());
    pUserPMSignalMapper->setMapping(pUserPMAction,pLWI->text());
    pUserProfileSignalMapper->setMapping(pUserProfileAction,pLWI->text());

    // We are showing the menu a bit earlier, to get the real size of the menu
    pUserMenu->show();

    pUserMenu->move(QCursor::pos());

    if ( !isConnected )
    {
        pUserNameAction->setEnabled(false);
    }
}

void OnelinerWidget :: addNameInMessage(const QString& userName)
{
    qDebug() << "OnelinerWidget :: addNameInMessage " << userName;

    pInput->setText(pInput->text().prepend(userName + QString(" >")));
}

void OnelinerWidget :: goToUserPageViewer(const QString& userName)
{
    qDebug() << "OnelinerWidget :: goToUserPageViewer" << userName;

    emit needRequestUserPage(userName);
}

void OnelinerWidget :: openPMPage(const QString& userName)
{
    qDebug() << "OnelinerWidget :: openPMPage " << userName;

    // This has to be changed because I don't know yet the name of the url
    QDesktopServices::openUrl(QString(DEFAULT_SERVER) + QString(SEND_PM_PATH) + userName);
}

void OnelinerWidget :: openProfilePage(const QString& userName)
{
    qDebug() << "OnelinerWidget :: openProfilePage " << userName;

    // This has to be changed to accept more than one server
    QDesktopServices::openUrl(QString(DEFAULT_SERVER) + QString(USER_PATH) + userName);
}
